package Control;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import Flight.Flight;
import Operaciones.Constantes;

public class PanelTerminal extends JPanel implements Observer{

	private static final long serialVersionUID = -1863238179433313055L;
	// Declaración generica de una lista
	private JLabel titlePanel;
	private JLabel selVuelo;

	private JComboBox combo;
	private JTextArea info;
	private JTextField numVuelo;
	private JButton cambiarEstado;
	
	private Terminal ter;
	
	public PanelTerminal(String nombrePanel, int puerto){
		// Creamos la Terminal
		this.ter = new Terminal(nombrePanel, puerto);
	    // Este panel observará cambios en la Terminal.
	    this.ter.addObserver(this);
		
		this.setSize(Constantes.ANCHO_VENTANA,Constantes.ALTO_VENTANA);
		this.setLayout(new GridBagLayout());
		insertarOpciones();
		inicializarPanel();
	    this.setVisible(true);

	    // Una vez que nos añadimos como observadores nos conectamos con Spread
	    this.ter.conexionSpread();
	}
	
	private void insertarOpciones(){
		combo = new JComboBox();

		combo.addItem("Autorizar embarque");
		combo.addItem("Autorizar despegue");
		combo.addItem("Confirmar despegue");
		combo.addItem("Autorizar aterrizaje");
		combo.addItem("Autorizar desembarque");
		combo.addItem("Confirmar aterrizaje completo");

		// Selecionamos el primero por defecto.
		combo.setSelectedIndex(0);
		
		// Inicializamos un titulo del panel
		titlePanel = new JLabel("Selecciona una de las siguientes opciones:");
		
		// Inicializar campo de información
		info = new JTextArea("",1,1);
		
		// Inicializamos el label de seleccionar vuelo
		selVuelo = new JLabel("Selecciona el número de vuelo");

		// Inicializar campo de información
		numVuelo = new JTextField(10);
		
		// Inicializar boton de cambio de vuelo
		cambiarEstado = new JButton("Cambiar estado vuelo");
	}
	
	private void inicializarPanel() {

		
		// Accion a realizar cuando el JComboBox cambia de item seleccionado.
		combo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String messageError = "Ningún vuelo se encuentra en esta lista";
				
				int opcion = combo.getSelectedIndex();
				
				switch (opcion){
				case 0: 
						String cad0 = ter.showFlight(ter.getListDeparture(), Constantes.PREPARADO);
						if (cad0 != null){
							valido(true);
							info.setText(cad0);
						}else{
							informarError(messageError);
						}
						break;
				case 1:
						String cad1 = ter.showFlight(ter.getListDeparture(), Constantes.EMBARCANDO);
						if (cad1 != null){
							valido(true);
							info.setText(cad1);
						}else{
							informarError(messageError);
						}
						break;
				case 2: 
						String cad2 = ter.showFlight(ter.getListDeparture(), Constantes.DESPEGANDO);
						if (cad2 != null){
							valido(true);
							info.setText(cad2);
						}else{
							informarError(messageError);
						}
						break;

				case 3:
						String cad5 = ter.showFlight(ter.getListArrival(), Constantes.PREPARADO_ATERRIZAR);
						if (cad5 != null){
							valido(true);
							info.setText(cad5);
						}else{
							informarError(messageError);
						}
						break;
				case 4:
						String cad6 = ter.showFlight(ter.getListArrival(), Constantes.ATERRIZANDO);
						if (cad6 != null){
							valido(true);
							info.setText(cad6);
						}else{
							informarError(messageError);
						}
						break;
				case 5:
						String cad7 = ter.showFlight(ter.getListArrival(), Constantes.DESEMBARCANDO);
						if (cad7 != null){
							valido(true);
							info.setText(cad7);
						}else{
							informarError(messageError);
						}
						break;
				default:
						
						break;
				}
			}
		});
		
		// Accion a realizar cuando el JComboBox cambia de item seleccionado.
		cambiarEstado.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// Cogemos la opción seleccionada.
				int opcion = combo.getSelectedIndex();

				switch (opcion){
				case 0: 
						String idFlightRd = numVuelo.getText();
						if (idFlightRd != null) {
							if (ter.changeStatus(ter.getListDeparture(),idFlightRd,Constantes.PREPARADO,Constantes.EMBARCANDO)){
								ter.sendMessage_Departure();
								ter.sendMessage_Terminal();
								repaint(ter.getListDeparture(),Constantes.PREPARADO);
							}
							else {
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				case 1:
						String idFlightRe = numVuelo.getText();
						if (idFlightRe != null) {
							if (ter.changeStatus(ter.getListDeparture(),idFlightRe,Constantes.EMBARCANDO, Constantes.DESPEGANDO)){
								ter.sendMessage_Departure();
								ter.sendMessage_Terminal();
								repaint(ter.getListDeparture(),Constantes.EMBARCANDO);
							}
							else{
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				case 2: 
						String idFlightD = numVuelo.getText();
						if (idFlightD != null) {
							if (ter.changeStatus(ter.getListDeparture(),idFlightD,Constantes.DESPEGANDO, Constantes.DESPEGUE)){
								ter.sendMessage_Departure();
								ter.sendMessage_Terminal();
								repaint(ter.getListDeparture(),Constantes.DESPEGANDO);
							} else {
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				case 3:
						String idFlightP = numVuelo.getText();
						if (idFlightP != null) {
							if (ter.changeStatus(ter.getListArrival(),idFlightP,Constantes.PREPARADO_ATERRIZAR, Constantes.ATERRIZANDO)){
								ter.sendMessage_Arrival();
								ter.sendMessage_Terminal();
								repaint(ter.getListArrival(),Constantes.PREPARADO_ATERRIZAR);
							} else {
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				case 4:
						String idFlightDes = numVuelo.getText();
						if (idFlightDes != null) {
							if (ter.changeStatus(ter.getListArrival(),idFlightDes,Constantes.ATERRIZANDO, Constantes.DESEMBARCANDO)){
								ter.sendMessage_Arrival();
								ter.sendMessage_Terminal();
								repaint(ter.getListArrival(),Constantes.ATERRIZANDO);
						} else {
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				case 5:
						String idFlightAte = numVuelo.getText();
						if (idFlightAte != null) {
							if (ter.changeStatus(ter.getListArrival(),idFlightAte,Constantes.DESEMBARCANDO, Constantes.ATERRIZADO)){
								ter.sendMessage_Arrival();
								ter.sendMessage_Terminal();
								repaint(ter.getListArrival(),Constantes.DESEMBARCANDO);
							} else {
								informarError("No se ha encontrado ningún vuelo con ese identificador");
							}
						}
						break;
				default: 
						break;
				}
			}
		});
		// Establecemos como estado inical que muestre vuelos de salidas.
		repaint(ter.getListDeparture(),Constantes.PREPARADO);
		
		GridBagConstraints c = new GridBagConstraints();
		
		c.weightx = 1.0; c.weighty = 1.0;
		c.fill = GridBagConstraints.NONE;
		c.anchor = GridBagConstraints.CENTER;
		
		c.gridx = 0;
		c.gridy = 0;
			this.add(this.titlePanel,c);

		c.gridx = 0;
		c.gridy = 1;
			this.add(this.combo,c);
		
		c.gridx = 0;
		c.gridy = 2;
			this.add(this.info,c);

		c.gridx = 0;
		c.gridy = 3;
			this.add(this.selVuelo,c);
		
		c.gridx = 0;
		c.gridy = 4;
			this.add(this.numVuelo,c);

		c.gridx = 0;
		c.gridy = 5;
			this.add(this.cambiarEstado,c);
	}
	
	public void update(Observable ob, Object o) {
		if (ob != null){
			repaintAll();
		}
	}
	
	public void repaintAll(){
		
		repaint(this.ter.getListArrival(),Constantes.PREPARADO_ATERRIZAR);
		repaint(this.ter.getListArrival(),Constantes.ATERRIZADO);
		repaint(this.ter.getListArrival(),Constantes.ATERRIZANDO);
		repaint(this.ter.getListArrival(),Constantes.DESEMBARCANDO);
		
		repaint(this.ter.getListDeparture(),Constantes.EMBARCANDO);
		repaint(this.ter.getListDeparture(),Constantes.DESPEGANDO);
		repaint(this.ter.getListDeparture(),Constantes.DESPEGUE);
		repaint(this.ter.getListDeparture(),Constantes.PREPARADO);

	}
	
	public void repaint(List<Flight> listaVuelos, String estado){
		String cad = ter.showFlight(listaVuelos, estado);
		if (cad != null){
			valido(true);
			info.setText(cad);
		}else{
			//informarError("Ningún vuelo se encuentra en esta lista");
			info.setText("");
		}
	}
	
	public void informarError(String message){
		valido(false);
		JOptionPane.showMessageDialog(new JFrame(), message, "Dialog",JOptionPane.ERROR_MESSAGE);
	}
	
	public void valido (boolean opcion){
		if (opcion){
			this.numVuelo.setVisible(opcion);
			this.info.setVisible(opcion);
			this.cambiarEstado.setVisible(opcion);
			this.selVuelo.setVisible(opcion);
		} else {
			this.numVuelo.setVisible(opcion);
			this.info.setVisible(opcion);
			this.cambiarEstado.setVisible(opcion);
			this.selVuelo.setVisible(opcion);
		}
	}
}
